/*
 * @Descripttion:  基础请求方式 get、post、put、del、postReq（content-type封装）、binaryReq（响应体arraybuffer）、blobReq（响应体blob）
 * @version:
 * @Author: lhl
 * @Date: 2024-09-13 16:20:20
 * @LastEditors: lhl
 * @LastEditTime: 2024-10-25 10:07:21
 */

import request from '@/utils/request';
import { AxiosRequestConfig } from 'axios';

// 定义通用请求函数类型
type RequestFunction = <T = unknown>(
  url: string,
  data?: Record<string, unknown>,
  config?: AxiosRequestConfig
) => Promise<T>;

// 封装 GET 请求方法
export const get: RequestFunction = (url, params, config) => {
  return request({
    url,
    method: 'get',
    params,
    ...config
  });
};

// 封装 POST 请求方法 默认json格式
export const post: RequestFunction = (url, data, config) => {
  return request({
    url,
    method: 'post',
    data,
    ...config
  });
};

// 封装 PUT 请求方法
export const put: RequestFunction = (url, data, config) => {
  return request({
    url,
    method: 'put',
    data,
    ...config
  });
};

// 封装 DELETE 请求方法
export const del: RequestFunction = (url, params, config) => {
  return request({
    url,
    method: 'delete',
    params,
    ...config
  });
};

// 封装 POST 请求方法，根据 Content-Type 处理数据
export function postReq(
  url: string,
  data?: Record<string, unknown>,
  contentType: 'json' | 'form' | 'multipart' = 'json',
  config?: AxiosRequestConfig
) {
  let processedData: string | FormData | Record<string, unknown> = data || {};

  const headers: Record<string, string> = {};

  if (config?.headers) {
    Object.entries(config.headers).forEach(([key, value]) => {
      if (typeof value === 'string') {
        headers[key] = value;
      }
    });
  }

  switch (contentType) {
    case 'json': {
      headers['Content-Type'] = 'application/json';
      processedData = JSON.stringify(processedData);
      break;
    }
    case 'form': {
      headers['Content-Type'] = 'application/x-www-form-urlencoded';
      processedData = new URLSearchParams(processedData as Record<string, string>).toString();
      break;
    }
    case 'multipart': {
      headers['Content-Type'] = 'multipart/form-data';
      const formData = new FormData();
      Object.entries(processedData).forEach(([key, value]) => {
        if (value != null && value !== '') {
          formData.append(key, value as string | Blob);
        }
      });
      processedData = formData;
      break;
    }
    default:
      throw new Error('不支持的 Content-Type');
  }

  return request({
    url,
    method: 'post',
    data: processedData,
    headers,
    ...config
  });
}

// 封装返回二进制响应体的请求方法
export function binaryReq(
  url: string,
  method: 'get' | 'post' = 'get',
  data?: Record<string, unknown>,
  config?: AxiosRequestConfig
) {
  return request({
    url,
    method,
    data,
    responseType: 'arraybuffer',
    ...config
  });
}

// 封装返回 Blob 响应体的请求方法
export function blobReq(
  url: string,
  method: 'get' | 'post' = 'get',
  data?: Record<string, unknown>,
  config?: AxiosRequestConfig
) {
  return request({
    url,
    method,
    data,
    responseType: 'blob',
    ...config
  });
}
